iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
自我挑戰組

Unit Test 學習路系列 第 24

Day 23: keyboard interaction

  • 分享至 

  • xImage
  •  

今天來練習撰寫 keyboard interaction (輸入 type、切換 tab) 的寫法。

使用情境
延伸昨日畫面上包含四個 Element:兩個按鈕,一個輸入框,一個顯示數字的 heading。
畫面上包含四個 Element:兩個按鈕,一個輸入框,一個顯示數字的 heading。

import { useState } from "react"

export default function Counter(){
    const [ counter, setCounter ] = useState(0);

    return(
        <>
            <h1>{counter}</h1>
            <div>
                <label htmlFor="type">Type Number</label>
                <input 
                    type="number" 
                    name="Type" 
                    id="type" 
                    value={counter}
                    onChange={(e) => setCounter(Number(e.target.value))} 
                />
            </div>
            <div>
                <button onClick={() => setCounter(pre => pre+1)}>+ 1</button>
                <button onClick={() => setCounter(pre => pre-1)}>- 1</button>
            </div>
        </>
    )
}

先確認四個元素都有出現在畫面上:

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Counter from "./counter";

describe("Counter", () => {
    // (1) 檢查四個元素是否有正確顯示在畫面上,與初始值
    test("Render correctly!", () => {
        render(<Counter />);

        const counterEl = screen.getByRole("heading", {
            level: 1
        });
        expect(counterEl).toHaveTextContent("0"); // 記得要輸入的是字串型別

        const addBtnEl = screen.getByRole("button", {
            name: "Add 1"
        });
        expect(addBtnEl).toBeInTheDocument();

        const minusBtnEl = screen.getByRole("button", {
            name: "Minus 1"
        });
        expect(minusBtnEl).toBeInTheDocument();

        const inputNumberBtnEl = screen.getByRole("spinbutton");
        expect(inputNumberBtnEl).toBeInTheDocument();   
    });
});

測試結果:
PASS src/components/counter/counter.test.tsx

keyboard interaction: type

確認透過鍵盤輸入數字,改變畫面顯示內容

撰寫測試:

describe("Counter", () => {
    // (3) 模擬使用者鍵盤輸入數字
    test("Change Number when typing", async () => {
        render(<Counter />);

        const inputNumberBtnEl = screen.getByRole("spinbutton");
        await userEvent.type(inputNumberBtnEl, "23");
        expect(inputNumberBtnEl).toHaveValue(23); // 確認輸入框符合鍵盤輸入內容

        const counterEl = screen.getByRole("heading", {
            level: 1
        });
        expect(counterEl).toHaveTextContent("23"); // 確認畫面顯示符合鍵盤輸入內容
    })
});

測試結果:
PASS src/components/counter/counter.test.tsx


keyboard interaction: tab

預期使用者鍵盤輸入 Tab,畫面上的輸入框 與 按鈕會依序 onFocus 的狀態。

撰寫測試:Tab 依序 輸入框 -> 加一按鈕 -> 減一按鈕。

describe("Counter", () => {

    // (4) 模擬使用者鍵盤 Tab,每個元素依序 onFocus
    test("Focus Element by order", async () => {
        render(<Counter />);

        
        const inputNumberBtnEl = screen.getByRole("spinbutton");
        const addBtnEl = screen.getByRole("button", {
            name: "Add 1"
        });
        const minusBtnEl = screen.getByRole("button", {
            name: "Minus 1"
        });

        await userEvent.tab();
        expect(inputNumberBtnEl).toHaveFocus();
        await userEvent.tab();
        expect(addBtnEl).toHaveFocus();
        await userEvent.tab();
        expect(minusBtnEl).toHaveFocus();
    });
});

測試結果:
PASS src/components/counter/counter.test.tsx


參考資源


上一篇
Day 22: Pointer(Mouse) Interactions
下一篇
Day 24: How to test Provider?
系列文
Unit Test 學習路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言